package com.mjk.common.core.redis.datatype;

import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 * redis 工具类 操作HASH 结构数据
 * 
 * @author mjk
 *
 */
public class RedisHashUtils {

	private RedisHashUtils(){}

	public static void setCacheHash(RedisTemplate<String, Object> redisTemplate,
			final Map<String, Map<String, String>> map) {
		redisTemplate.execute((RedisCallback<Integer>) connection -> {
            connection.openPipeline();
            for (Entry<String, Map<String, String>> entry : map.entrySet()) {
                for (Entry<String, String> entry1 : entry.getValue().entrySet()) {
                    connection.hSet(entry.getKey().getBytes(), entry1.getKey().getBytes(),
                            entry1.getValue().getBytes());
                }
            }
            connection.closePipeline();
            return 0;
        });
	}
	/**
	 * @description 设置hash的键、属性和值。此方法写的比较死，无法做到通用
     */
	public static void set(RedisTemplate<String, Object> redisTemplate,String key, String hKye,Object value) {
		HashOperations<String, String, Object> oper = redisTemplate.opsForHash();
		oper.put(key, hKye, value);		
	}
		
	
	/**
	 * @description 根据hash的键（key）和属性(hKye)查询出对应的属性
     */
	public static Object get(RedisTemplate<String, Object> redisTemplate,String key, String hKye) {
		HashOperations<String, String, Object> oper = redisTemplate.opsForHash();
		return oper.get(key, hKye);		
	}

	/**
	 * @description 获取键(key)下面的所有属性
     */
	public static List<String> getKeys(RedisTemplate<String, Object> redisTemplate,String key) {
		HashOperations<String, String, Object> oper = redisTemplate.opsForHash();
		Set<String> set = oper.keys(key);
		return new ArrayList<>(set);
	}

	/**
	 * @description 获取键(key)下面的所有值
     */
	public static List<Object> getValues(RedisTemplate<String, Object> redisTemplate,String key) {
		HashOperations<String, String, Object> oper = redisTemplate.opsForHash();
		return oper.values(key);
	}

	/**
	 * @description 根据键获取属性个数
     */
	public static int length(RedisTemplate<String, Object> redisTemplate,String key) {
		HashOperations<String, String, Object> oper = redisTemplate.opsForHash();
		return oper.size(key).intValue();
	}

	/**
	 * 自增
	 *
	 * @param redisTemplate
	 * @param key
	 * @param hash
	 * @return
	 */
	public static int incr(RedisTemplate redisTemplate, String key, String hash) {
		HashOperations<String, String, Object> oper = redisTemplate.opsForHash();
		return oper.increment(key, hash, 1).intValue();
	}
	/**
	 * @description 判断键是否存在
     */
	public static boolean exists(RedisTemplate<String, Object> redisTemplate,String key,String hashKey) {
		HashOperations<String, String, Object> oper = redisTemplate.opsForHash();
		return oper.hasKey(key, hashKey);		
	}

	/**
	 * @description 删除指定的键（key）下面的属性（hashKeys）
     */

	public static void delete(RedisTemplate<String, Object> redisTemplate,String key, Object... hashKeys) {
		HashOperations<String, String, Object> oper = redisTemplate.opsForHash();
		oper.delete(key, hashKeys);
	}
	/**
	 * 获取key下的所有hash键值对
     */
	public static Map<String,Object> getHashAll(RedisTemplate<String, Object> redisTemplate,String key){
		HashOperations<String, String, Object> oper = redisTemplate.opsForHash();
		return oper.entries(key);
	}
	/**
	 * 如果不存在就放入，存在就不放入
     */
	public static boolean putIfAbsent(RedisTemplate<String, Object> redisTemplate,String key, String hKye,Object value) {
		HashOperations<String, String, Object> oper = redisTemplate.opsForHash();
		return oper.putIfAbsent(key, hKye, value);
	}
}
